20540
4936
Αφού διάβασα τα κρυμμένα χαρακτηριστικά και τις σκοτεινές γωνίες του C ++ / STL στο comp.lang.c ++. Με εποπτεία, με εξέπληξε εντελώς ότι το παρακάτω απόσπασμα συνέταξε και δούλεψε τόσο στο Visual Studio 2008 όσο και στο G ++ 4.4.
Εδώ είναι ο κωδικός:
# συμπερίληψη 
int main ()
{
int x = 10;
ενώ (x -> 0) // x πηγαίνει στο 0
{
printf ("% d", x);
}
}
Παραγωγή:
9 8 7 6 5 4 3 2 1 0
Θα υποθέσω ότι είναι C, καθώς λειτουργεί και στο GCC. Από πού ορίζεται αυτό στο πρότυπο και από πού προέρχεται; 
-> δεν είναι χειριστής. Στην πραγματικότητα είναι δύο ξεχωριστοί τελεστές, - και>.
Ο κώδικας υπό όρους μειώνει το x, ενώ επιστρέφει την αρχική τιμή του x (δεν έχει μειωθεί) και στη συνέχεια συγκρίνει την αρχική τιμή με το 0 χρησιμοποιώντας τον τελεστή>.
Για καλύτερη κατανόηση, η δήλωση θα μπορούσε να γραφτεί ως εξής:
ενώ ((x--)> 0)
|
Ή για κάτι εντελώς διαφορετικό ... x διαφάνειες στο 0.
ενώ (x - \
\
\
\
> 0)
printf ("% d", x);
Όχι τόσο μαθηματικά, αλλά ... κάθε εικόνα χρωματίζει χίλιες λέξεις ...
|
Αυτός είναι ένας πολύ περίπλοκος χειριστής, οπότε ακόμη και το ISO / IEC JTC1 (Κοινή Τεχνική Επιτροπή 1) έβαλε την περιγραφή του σε δύο διαφορετικά μέρη του προτύπου C ++.
Αστειεύοντας, είναι δύο διαφορετικοί χειριστές: - και> περιγράφονται αντίστοιχα στα §5.2.6 / 2 και §5.9 του C ++ 03 Standard.
|
Είναι ισοδύναμο με
ενώ (x--> 0)
x-- (post decrement) ισοδυναμεί με x = x-1, ο κώδικας μετατρέπεται σε:
ενώ (x> 0) {
x = x-1;
// λογική
}
Χ--; // Η μείωση μετά έγινε όταν x <= 0
|
x μπορεί να πάει στο μηδέν ακόμη πιο γρήγορα στην αντίθετη κατεύθυνση:
int x = 10;
ενώ (0 <---- x)
{
printf ("% d", x);
}
8 6 4 2
Μπορείτε να ελέγξετε την ταχύτητα με ένα βέλος!
int x = 100;
ενώ (0 <-------------------- x)
{
printf ("% d", x);
}
90 80 70 60 50 40 30 20 10
;)
|
Του
# συμπερίληψη 
int main (άκυρο) {
int x = 10;
ενώ (x--> 0) {// x πηγαίνει στο 0
printf ("% d", x);
}
επιστροφή 0;
}
Μόνο ο χώρος κάνει τα πράγματα να φαίνονται αστεία, - μειώσεις και> συγκρίνει.
|
Η χρήση του -> έχει ιστορική σημασία. Η μείωση ήταν (και εξακολουθεί να είναι σε ορισμένες περιπτώσεις), γρηγορότερη από την αύξηση της αρχιτεκτονικής x86. Η χρήση -> υποδηλώνει ότι το x πηγαίνει στο 0 και απευθύνεται σε άτομα με μαθηματικό υπόβαθρο.
|
ενώ (x--> 0)
είναι πώς αναλύεται.
|
Εντελώς geek, αλλά θα το χρησιμοποιήσω:
# ορίστε ως; ενώ
int main (int argc, char * argv [])
{
int n = atoi (argv [1]);
εκτυπώστε ("το n είναι% d \ n", n) ως (n -> 0);
επιστροφή 0;
}
|
Ένα βιβλίο που διάβασα (δεν θυμάμαι σωστά ποιο βιβλίο) δήλωσε: Οι μεταγλωττιστές προσπαθούν να αναλύσουν τις εκφράσεις στο μεγαλύτερο διακριτικό χρησιμοποιώντας τον αριστερό δεξιό κανόνα.
Σε αυτήν την περίπτωση, η έκφραση:
x -> 0
Αναλύει τα μεγαλύτερα διακριτικά:
διακριτικό 1: x
διακριτικό 2: -
διακριτικό 3:>
διακριτικό 4: 0
συμπέρασμα: x--> 0
Ο ίδιος κανόνας ισχύει για αυτήν την έκφραση:
α ----- β
Μετά την ανάλυση:
διακριτικό 1: α
διακριτικό 2: -
διακριτικό 3: -
διακριτικό 4: -
διακριτικό 5: β
συμπέρασμα: (α -) - - β
Ελπίζω ότι αυτό βοηθά στην κατανόηση της περίπλοκης έκφρασης ^^
|
Αυτό είναι ακριβώς το ίδιο με
ενώ (x--)
{
printf ("% d", x);
}
για μη αρνητικούς αριθμούς
|
Τέλος πάντων, έχουμε έναν χειριστή "πηγαίνει σε" τώρα. "->" είναι εύκολο να θυμηθούμε ως κατεύθυνση, και "ενώ το x πηγαίνει στο μηδέν" σημαίνει ευθεία.
Επιπλέον, είναι λίγο πιο αποτελεσματικό από το "for (x = 10; x> 0; x -)" σε ορισμένες πλατφόρμες.
|
Αυτός ο κωδικός συγκρίνει πρώτα τα x και 0 και στη συνέχεια τις μειώσεις x. (Επίσης, στην πρώτη απάντηση: Είστε μετά τη μείωση του x και, στη συνέχεια, συγκρίνετε τα x και 0 με το χειριστή>.) Δείτε την έξοδο αυτού του κωδικού:
9 8 7 6 5 4 3 2 1 0
Συγκρίνουμε τώρα πρώτα και μετά μειώνοντας βλέποντας 0 στην έξοδο.
Εάν θέλουμε πρώτα να μειώσουμε και μετά να συγκρίνουμε, χρησιμοποιήστε αυτόν τον κωδικό:
# συμπερίληψη 
int main (άκυρο)
{
int x = 10;
ενώ (--x> 0) // x πηγαίνει στο 0
{
printf ("% d", x);
}
επιστροφή 0;
}
Αυτή η έξοδος είναι:
9 8 7 6 5 4 3 2 1
|
Ο μεταγλωττιστής μου θα εκτυπώσει 9876543210 όταν εκτελώ αυτόν τον κωδικό.
# συμπερίληψη 
int main ()
{
int x = 10;
ενώ (x -> 0) // x πηγαίνει στο 0
{
std :: cout << x;
}
}
Οπως αναμενόταν. Το while (x--> 0) σημαίνει στην πραγματικότητα ενώ (x> 0). Οι x - μετά τις μειώσεις x.
ενώ (x> 0)
{
Χ--;
std :: cout << x;
}
είναι ένας διαφορετικός τρόπος να γράφεις το ίδιο πράγμα.
Είναι ωραίο ότι το πρωτότυπο μοιάζει με "ενώ το x πηγαίνει στο 0".
|
Λείπει κενό μεταξύ - και>. Το x είναι post decremented, δηλαδή μειώθηκε μετά τον έλεγχο της συνθήκης x> 0?
|
- είναι ο τελεστής μείωσης και> είναι ο τελεστής μεγαλύτερος από αυτόν.
Οι δύο τελεστές εφαρμόζονται ως ενιαίοι όπως ->.
|
Είναι ένας συνδυασμός δύο χειριστών. Πρώτον - είναι για τη μείωση της τιμής και> για τον έλεγχο εάν η τιμή είναι μεγαλύτερη από το δεξί τελεστέο.
# συμπερίληψη 
int main ()
{
int x = 10;
ενώ (x--> 0)
printf ("% d", x);
επιστροφή 0;
}
Η έξοδος θα είναι:
9 8 7 6 5 4 3 2 1 0
|
Στην πραγματικότητα, το x είναι μετά τη μείωση και ελέγχεται με αυτήν την κατάσταση Δεν είναι ->, είναι (x--)> 0
Σημείωση: η τιμή του x αλλάζει μετά τον έλεγχο της συνθήκης, επειδή μετά τη μείωση. Ορισμένες παρόμοιες περιπτώσεις μπορούν επίσης να συμβούν, για παράδειγμα:
-> x -> 0
++> x ++> 0
-> = x -> = 0
++> = x ++> = 0
|
Οι C και C ++ συμμορφώνονται με τον κανόνα «μέγιστο munch». Με τον ίδιο τρόπο a --- b μεταφράζεται σε (a--) - b, στην περίπτωσή σας x -> 0 μεταφράζεται σε (x -)> 0.
Αυτό που ουσιαστικά λέει ο κανόνας είναι ότι πηγαίνοντας αριστερά προς τα δεξιά, οι εκφράσεις σχηματίζονται λαμβάνοντας το μέγιστο των χαρακτήρων που θα σχηματίσουν μια έγκυρη έκφραση.
|
Γιατί όλη η επιπλοκή;
Η απλή απάντηση στην αρχική ερώτηση είναι απλώς:
# συμπερίληψη 
int main ()
{
int x = 10;
ενώ (x>0)
{
printf ("% d", x);
x = x-1;
}
}
Κάνει το ίδιο πράγμα. Δεν λέω ότι πρέπει να το κάνετε έτσι, αλλά κάνει το ίδιο πράγμα και θα απαντούσατε στην ερώτηση σε μία ανάρτηση.
Το x-- είναι μόνο συντομογραφία για τα παραπάνω και> είναι απλώς ένας κανονικός μεγαλύτερος από τον τελεστή. Χωρίς μεγάλο μυστήριο!
Υπάρχουν πάρα πολλοί άνθρωποι που κάνουν τα απλά πράγματα περίπλοκα σήμερα;)
|
Με τον συμβατικό τρόπο θα ορίζαμε μια συνθήκη στην παρένθεση while loop () και μια συνθήκη τερματισμού μέσα στα άγκιστρα {}, αλλά -> ορίζει και τα δύο ταυτόχρονα.
Για παράδειγμα:
int abc (άκυρο)
{
int a = 5
ενώ ((a--)> 0) // Μείωση και σύγκριση και τα δύο ταυτόχρονα
{
// Κωδικός
}
}
Αυτό μειώνεται και τρέχει το βρόχο ενώ το α είναι μεγαλύτερο από 0.
Συμβατικά, θα ήταν σαν:
int abc (άκυρο)
{
int a = 5;
ενώ (a> 0)
{
ένα--;
// Κωδικός
}
ένα--;
}
Και με τους δύο τρόπους, κάνουμε το ίδιο πράγμα και επιτυγχάνουμε τους ίδιους στόχους.
|
(x -> 0) σημαίνει (x--> 0).
Μπορείτε να χρησιμοποιήσετε (x ->) Έξοδος: 9 8 7 6 5 4 3 2 1 0
Μπορείτε να χρησιμοποιήσετε (- x> 0) Είναι μέση (--x> 0) Έξοδος: 9 8 7 6 5 4 3 2 1
Μπορείς να χρησιμοποιήσεις
(- \
\
x> 0)
Έξοδος: 9 8 7 6 5 4 3 2 1
Μπορείς να χρησιμοποιήσεις
(\
\
x -> 0)
Έξοδος: 9 8 7 6 5 4 3 2 1 0
Μπορείς να χρησιμοποιήσεις
(\
\
x -> 0
\
\
)
Έξοδος: 9 8 7 6 5 4 3 2 1 0
Μπορείτε επίσης να χρησιμοποιήσετε
(
Χ
->
)
Έξοδος: 9 8 7 6 5 4 3 2 1 0
Ομοίως, μπορείτε να δοκιμάσετε πολλές μεθόδους για να εκτελέσετε αυτήν την εντολή με επιτυχία.
|
Εδώ - είναι ο μη λειτουργικός τελεστής μετά τη μείωση.
ενώ (x--> 0) // x πηγαίνει στο 0
{
printf ("% d", x);
}
Στην αρχή, η κατάσταση θα αξιολογηθεί ως
(x> 0) // 10> 0
Τώρα επειδή η συνθήκη είναι αληθινή, θα πάει στο βρόχο με μια μειωμένη τιμή
x-- // x = 9
Γι 'αυτό η πρώτη εκτυπωμένη τιμή είναι 9
Και ούτω καθεξής. Στο τελευταίο βρόχο x = 1, έτσι η συνθήκη είναι αληθής. Σύμφωνα με τον unary τελεστή, η τιμή άλλαξε σε x = 0 τη στιγμή της εκτύπωσης.
Τώρα, x = 0, που αξιολογεί την κατάσταση (x> 0) ως ψευδής και ο βρόχος while εξέρχεται.
|
Αυτό -> δεν είναι καθόλου χειριστής. Έχουμε έναν χειριστή όπως ->, αλλά όχι όπως ->. Είναι απλώς μια λανθασμένη ερμηνεία του while (x--> 0) που σημαίνει απλά ότι x έχει τον τελεστή μετά τη μείωση και αυτός ο βρόχος θα τρέξει μέχρι να είναι μεγαλύτερος από το μηδέν.
Ένας άλλος απλός τρόπος σύνταξης αυτού του κώδικα θα ήταν το (x--). Ο βρόχος while θα σταματήσει κάθε φορά που παίρνει μια λανθασμένη κατάσταση και εδώ υπάρχει μόνο μία περίπτωση, δηλαδή 0. Έτσι θα σταματήσει όταν η τιμή x μειώνεται στο μηδέν.
|
Πολύ ενεργή ερώτηση. Κερδίστε 10 φήμη για να απαντήσετε σε αυτήν την ερώτηση. Η απαίτηση φήμης συμβάλλει στην προστασία αυτής της ερώτησης από ανεπιθύμητες ενέργειες και μη απαντήσεις.
Δεν είναι η απάντηση που ψάχνετε; Περιηγηθείτε σε άλλες ερωτήσεις με ετικέτες χειριστών c ++ c πρότυπα-μορφοποίηση προτύπων-συμμόρφωση ή κάντε τη δική σας ερώτηση.